import { ModernBaseService } from './base/ModernBaseService';
import { DIContainer } from '../infrastructure/di';
import { config, configKey } from '../config';
import { ItemType } from '../shared/face/enums';
import { TaskService } from './TaskService';
import { TaskTargetType } from '../core/rpg/types/task';

/**
 * 现代化签到服务
 * 使用依赖注入和现代架构模式
 */
export class ModernSignService extends ModernBaseService {
    
    constructor(container?: DIContainer) {
        super(container);
    }

    async init(): Promise<void> {
        console.log('ModernSignService initialized successfully');
    }

    async destroy(): Promise<void> {
        console.log('ModernSignService destroyed');
    }

    getServiceName(): string {
        return 'ModernSignService';
    }

    /**
     * 检查是否可以签到
     * @param lastSignDate 上次签到时间
     * @returns 是否可以签到
     */
    canSign(lastSignDate?: string): boolean {
        if (!lastSignDate) return true;
        
        const lastSign = new Date(lastSignDate);
        const now = new Date();
        
        // 获取今天的凌晨4点时间
        const today4am = new Date(now);
        today4am.setHours(4, 0, 0, 0);
        
        // 如果上次签到时间在今天凌晨4点之前，则可以签到
        return lastSign < today4am;
    }

    /**
     * 处理签到逻辑
     * @param player 玩家对象
     * @returns 签到结果
     */
    async sign(player: any): Promise<{
        success: boolean;
        message: string;
        rewards?: any[];
        signData: any;
        completedTasks?: any[];
    }> {
        try {
            const signComponent = player.getComponent('sign') as any;
            if (!signComponent) {
                return {
                    success: false,
                    message: '签到组件未找到',
                    signData: {}
                };
            }

            const signData = signComponent.signData || {};
            const lastSignDate = signData.lastSignDate;
            
            // 检查是否可以签到
            if (!this.canSign(lastSignDate)) {
                return {
                    success: false,
                    message: '今天已经签到过了，明天再来吧！',
                    signData: signData
                };
            }

            // 更新签到数据
            const now = new Date();
            const today = now.toISOString().split('T')[0];
            
            // 计算连续签到天数
            let consecutiveDays = 1;
            if (lastSignDate) {
                const lastSign = new Date(lastSignDate);
                const yesterday = new Date(now);
                yesterday.setDate(yesterday.getDate() - 1);
                
                // 如果昨天签到了，连续天数+1
                if (lastSign.toISOString().split('T')[0] === yesterday.toISOString().split('T')[0]) {
                    consecutiveDays = (signData.consecutiveDays || 0) + 1;
                }
            }

            // 更新签到数据
            const newSignData = {
                ...signData,
                lastSignDate: today,
                consecutiveDays: consecutiveDays,
                totalSignDays: (signData.totalSignDays || 0) + 1
            };

            signComponent.signData = newSignData;

            // 获取签到奖励
            const rewards = this.getSignRewards(consecutiveDays);
            
            // 发放奖励
            if (rewards && rewards.length > 0) {
                const generatedRewards = this.generateRewards(rewards);
                
                // 将奖励添加到玩家背包
                const bagComponent = player.getComponent('bag') as any;
                if (bagComponent) {
                    generatedRewards.forEach(reward => {
                        bagComponent.addItem(reward);
                    });
                }
            }

            // 更新签到任务进度
            let completedTasks: any[] = [];
            try {
                const taskResult = await TaskService.updateTaskProgress(player, TaskTargetType.签到);
                if (taskResult.success && taskResult.completedTasks) {
                    completedTasks = taskResult.completedTasks;
                }
            } catch (error) {
                console.warn('Failed to update sign task progress:', error);
            }

            return {
                success: true,
                message: '签到成功！',
                rewards: this.generateRewards(rewards),
                signData: newSignData,
                completedTasks: completedTasks
            };

        } catch (error) {
            console.error('Sign operation failed:', error);
            return {
                success: false,
                message: '签到失败，请稍后重试',
                signData: {}
            };
        }
    }

    /**
     * 获取签到奖励
     * @param consecutiveDays 连续签到天数
     * @returns 奖励数组
     */
    private getSignRewards(consecutiveDays: number): any[] {
        // 查找对应的奖励配置
        const signRewards = config.get(configKey.配置_签到奖励表) as Map<string,any>;
        const rewardConfig = signRewards.get(consecutiveDays.toString());
        if (!rewardConfig) {
            // 如果超过配置的最大天数，使用最大天数的奖励
            const maxDay = Math.max(...Array.from(signRewards.keys()).map(k => parseInt(k)));
            return this.getSignRewards(maxDay);
        }
        
        return rewardConfig.rewards || [];
    }

    /**
     * 生成奖励道具
     * @param rewardConfigs 奖励配置
     * @returns 奖励道具数组
     */
    private generateRewards(rewardConfigs: any[]): any[] {
        const rewards: any[] = [];
        const rewardMap = new Map<string, any>(); // 用于合并相同类型的奖励
        
        rewardConfigs.forEach(config => {
            const count = Math.floor(Math.random() * (Number(config.max) - Number(config.min) + 1)) + Number(config.min);
            const key = `${config.type}_${config.id}`;
            
            if (rewardMap.has(key)) {
                rewardMap.get(key).count += count;
            } else {
                rewardMap.set(key, {
                    id: config.id,
                    type: config.type as ItemType,
                    count: count,
                    name: config.name || config.id
                });
            }
        });
        
        return Array.from(rewardMap.values());
    }

    /**
     * 获取签到状态
     * @param player 玩家对象
     * @returns 签到状态信息
     */
    getSignStatus(player: any): {
        canSign: boolean;
        consecutiveDays: number;
        totalSignDays: number;
        lastSignDate?: string;
    } {
        const signComponent = player.getComponent('sign') as any;
        if (!signComponent) {
            return {
                canSign: true,
                consecutiveDays: 0,
                totalSignDays: 0
            };
        }

        const signData = signComponent.signData || {};
        return {
            canSign: this.canSign(signData.lastSignDate),
            consecutiveDays: signData.consecutiveDays || 0,
            totalSignDays: signData.totalSignDays || 0,
            lastSignDate: signData.lastSignDate
        };
    }
}
